package it.sarasini.dmp;

import java.io.File;
import java.util.ArrayList;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;

public class AudioVideoPlayer {
	
	/*
	 * The Android multimedia framework
	 * ------------------------------------------------------------------------------------
	 * The Android multimedia framework includes support for encoding and decoding a 
	 * variety of common media types, so that you can easily integrate audio, video and 
	 * images into your applications. You can play audio or video from media files 
	 * stored in your application's resources (raw resources), from standalone files in 
	 * the filesystem, or from a data stream arriving over a network connection, all 
	 * using MediaPlayer APIs.
	 */
	
	/*
	 * Handler 
	 * -----------------------------------------------------------------------------------
	 * A Handler allows you to send and process Message and Runnable objects associated 
	 * with a thread's MessageQueue. Each Handler instance is associated with a single 
	 * thread and that thread's message queue. When you create a new Handler, it is bound 
	 * to the thread / message queue of the thread that is creating it -- from that point on, 
	 * it will deliver messages and runnables to that message queue and execute them as they 
	 * come out of the message queue. 
	 * There are two main uses for a Handler: (1) to schedule messages and runnables to be 
	 * executed as some point in the future; and (2) to enqueue an action to be performed on 
	 * a different thread than your own.
	 */
	
	protected ArrayList<AudioVideoPlayerTimeListener> listenerList;
	private Context context;
	private MediaPlayer mp;
	private Handler timeHandler;
	private Runnable timeRunnable;
	private final static int timeUpdateDelay = 800;
	

	public AudioVideoPlayer(Context c) {
		
		mp = new MediaPlayer();
		context = c;
		listenerList =  new ArrayList<AudioVideoPlayerTimeListener>();
		
		timeRunnable = new Runnable()
		{
		    public void run() 
		    {
		    	fireTimeChangedEvent(getPosition());
		    	
		    	if(isPlaying())
		    		timeHandler.postDelayed(this, timeUpdateDelay);
		    }
		};
	}
	
	public boolean loadAudioFile(File file) {
		
		mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
		
		try 
		{
			mp.setDataSource(context, Uri.fromFile(file));
			mp.prepare();
			
		} catch(Exception e) { return false; }
		
		timeHandler = new Handler();
		
		return true;
	}
	
	public void play() {
		
		mp.start();
		
		timeHandler.postDelayed(timeRunnable, timeUpdateDelay);
	}
	
	public void pause() {
		
		mp.pause();
		
		timeHandler.postDelayed(timeRunnable, timeUpdateDelay);
	}
	
	public boolean isPlaying() {
		
		return mp.isPlaying();
	}
	
	public void seekTo( int ms) {
		
		if(isPlaying())
			mp.seekTo(ms);
	}
	
	public int getPosition() {
		
		return mp.getCurrentPosition();
	}
	
	public int getDuration() {
		
		return mp.getDuration();
	}
	
	public void addAudioVideoPlayerTimeListener(AudioVideoPlayerTimeListener listener) {
		
        listenerList.add(listener);
    }
	
	public void removeAudioVideoPlayerTimeListener(AudioVideoPlayerTimeListener listener) {
		
        listenerList.remove(listener);
    }
	
	void fireTimeChangedEvent(int ms) {
		
        for(int i=0; i<listenerList.size(); i++) {
        	
        	listenerList.get(i).audioVideoPlayerTimeChanged(ms);
        }
    }
	
}
